package com.byron.media.server.sessions;

import com.byron.media.server.config.MediaServerConfig;
import com.byron.media.server.model.MediaData;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import lombok.extern.slf4j.Slf4j;

import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;


/**
 * 实际连接
 */
@Slf4j
//@ChannelHandler.Sharable
public class RealSession extends ChannelInboundHandlerAdapter {

    // 是否已激活
    private boolean active;
    private ChannelHandlerContext context;

    // 代理服务器相关属性
    private IProxyServer proxyServer;

    // 代理客户端相关属性
    private IProxyClient proxyClient;

    // 客户端相关属性
    private ClientSession clientSession;
    private boolean client;      // TODO 是否为客户端

    // 发送记录
    private Queue<Byte> history = new ConcurrentLinkedQueue<>();

    private Channel channel;


    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        super.channelActive(ctx);
        if(context == null){
            context = ctx;
            this.channel = ctx.channel();
        }
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        super.channelInactive(ctx);
        // 意外掉线



        // 如果是代理服务器掉线，则所有的代理session都掉线
        if(isProxyServer()){
            inactiveForProxyServer();
            return;
        }


        // 如果是客户掉线
        if(isClient()){
            inactiveForClient();
            return;
        }

        if(isProxyClient()){
            inactiveForProxyClient();
        }

    }


    /**
     * 以代理客户端的方式注销
     */
    private void inactiveForProxyClient() {
        this.active = false;
        proxyClient.inactive();
    }

    /**
     * 以客户端方式掉线
     */
    private void inactiveForClient() {
        if(clientSession != null){
            clientSession.inactive();
        }
        active = false;
    }


    /**
     * 代理方式断线
     */
    private void inactiveForProxyServer() {
        active = false;
        this.proxyServer.inactive();
    }

    /**
     * 是否为客户端
     */
    public boolean isClient() {
        return client;
    }

    /**
     * 发送数据
     * @param data
     */
    public void write(Object data) {
        if(context == null){
            return;
        }
        if(data.getClass() == MediaData.class){
            MediaData mediaData = (MediaData) data;

            // 防止循环发送
//            if(mediaData.getServerId() == this.serverId){
//                return;
//            }
            if(history.contains(mediaData.getSeq())){
                return;
            }
            history.offer(mediaData.getSeq());
            if(history.size() > 5){
                history.poll();
            }
        }
        context.writeAndFlush(data);
    }


    /**
     * 作为代理客户端激活
     */
    public void activeAsProxyClient(IProxyClient proxyClient){
        if(active){
            return;
        }
        this.proxyClient = proxyClient;
        active = true;
        if(MediaServerConfig.getInstance().isLog()){
            log.info("代理客户端连接成功");
        }
    }


    /**
     * 作为代理服务器进行激活
     */
    public void activeAsProxy(IProxyServer proxyServer) {
        if(active){
            return;
        }
        this.client = false;
        this.active = true;
        this.proxyServer = proxyServer;
        if(MediaServerConfig.getInstance().isLog()){
            log.info("代理服务器 连接成功");
        }
    }

    /**
     * 作为客户端被激活
     */
    public void activeAsClient(ClientSession session) {
        if(active){
            return;
        }
        this.client = true;
        this.clientSession = session;
        this.active = true;
        if(MediaServerConfig.getInstance().isLog()){
            log.info("客户端 连接成功");
        }
    }

    public boolean isActive(){
        return active;
    }


    /**
     * 是否为代理服务器
     * @return
     */
    public boolean isProxyServer() {
        return proxyServer != null;
    }

    /**
     * 是否未代理客户端
     * @return
     */
    public boolean isProxyClient(){
        return proxyClient != null;
    }


    /**
     * 进客户端有效，返回客户端联系
     */
    public ISession getClientSession() {
        return clientSession;
    }

    public IProxyServer getProxyServer() {
        return proxyServer;
    }

    public Channel getChannel() {
        return channel;
    }
}
